package caronas.dao;

import java.util.List;
import java.util.Set;

import org.hibernate.FetchMode;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.criterion.Restrictions;

import br.com.caelum.vraptor.ioc.Component;
import caronas.modelo.Carona;
import caronas.modelo.Service;
import caronas.modelo.Usuario;

@Component
public class UsuarioDao {
	
	private Session session;
	private SessionFactory factory;
	
	public UsuarioDao(Session session, SessionFactory factory) {
		AnnotationConfiguration configuration = new AnnotationConfiguration();
		configuration.configure();
		this.factory = factory;
		this.session = session;
		
	}
	
	@SuppressWarnings("unchecked")
	public List<Usuario> listar() {
		return session.createCriteria(Usuario.class).list();		
	}
	
	public void adicionar(Usuario usuario) {
		Transaction tx = session.beginTransaction();
		session.save(usuario);
		tx.commit();
	}
	
	public void atualizar(Usuario usuario) {
		Transaction tx = session.beginTransaction();
		session.update(usuario);
		tx.commit();
	}
	
	public Usuario carregar(Long id) {
		return (Usuario) session.load(Usuario.class, id);
	}
	
	/*
	public void recarregar(Usuario usuario) {
		Transaction tx = session.beginTransaction();
		session.refresh(usuario);
		tx.commit();
	}
	*/
	
	public void remover(Usuario usuario) {
		Transaction tx = session.beginTransaction();
		session.delete(usuario);
		tx.commit();
	}

	public Usuario carrega(Usuario usuario) {
		return (Usuario) session.createCriteria(Usuario.class)
				.add(Restrictions.eq("email", usuario.getEmail()))
				.add(Restrictions.eq("senha", usuario.getSenha()))
				.setFetchMode("passageiros", FetchMode.JOIN)
				.uniqueResult();
	}
	
	public Usuario carrega(Service service) {
		return (Usuario) session.createCriteria(Usuario.class)
				.createAlias("services", "ser")
				.add(Restrictions.eq("services.id", service.getId()))				
				.setFetchMode("passageiros", FetchMode.JOIN)
				.uniqueResult();
	}
	
	public Service buscaProvedorUsario(String provider, String userId){
		return (Service) session.createCriteria(Service.class)
				.add(Restrictions.eq("provider",provider))
				.add(Restrictions.eq("uid", userId))
				.setFetchMode("usuario.caronasPedidas", FetchMode.JOIN)
				.uniqueResult();
	}
	
	public void adicionarService(Service service){
		Transaction tx = session.beginTransaction();		
		session.save(service);
		tx.commit();
	}
	
	public Usuario getUsuario(Service service){
		return service.getUsuario();
	}
	
	public void updateServiceToken(Service service, String token){
		service.setAccessToken(token);
		Transaction tx = session.beginTransaction();		
		session.update(service);
		tx.commit();
	}
	
	public boolean pegouCarona(Usuario usuario, Carona carona){
	  	Set<Carona> caronas = usuario.getCaronasPedidas();
	  	for(Carona caronaPedida : caronas){
	  		if(caronaPedida.getId().compareTo( carona.getId()) == 0){
	  			return true;
	  		}
	  	}
		return false;
	}
	
}
